package com.tianjin.weight.shiro;

import com.alibaba.fastjson.JSON;
import com.tianjin.weight.constants.Constant;
import com.tianjin.weight.exception.BusinessException;
import com.tianjin.weight.exception.code.BaseResponseCode;
import com.tianjin.weight.utils.DataResult;
import com.tianjin.weight.utils.HttpContextUtils;
import com.tianjin.weight.utils.JwtTokenUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.springframework.util.StringUtils;

import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.OutputStream;

/**
 * @ClassName: CustomAccessControlFilter
 * TODO:类文件简单描述
 * @Author: 小霍
 * @CreateDate: 2019/9/6 23:22
 * @UpdateUser: 小霍
 * @UpdateDate: 2019/9/6 23:22
 * @Version: 0.0.1
 */
@Slf4j
public class CustomAccessControlFilter extends AccessControlFilter {
    @Override
    protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object o) {
        return false;
    }
    @Override
    protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws IOException, ServletException {
        HttpServletRequest request= (HttpServletRequest) servletRequest;
        try {
            Subject subject=getSubject(servletRequest,servletResponse);

            String token=request.getHeader(Constant.ACCESS_TOKEN);
            String loginType = request.getHeader("loginType");

            if(loginType==null) { //PC端请求
                //富文本上传图片请求
                if (request.getRequestURL().toString().contains("/pc/fuweben/upload")){
                    return true;
                }
                //根据企业名称查询用户请求
                if (request.getRequestURL().toString().contains("/pc/newProduct/companyByUser/")){
                    return true;
                }
                if(!request.getRequestURL().toString().contains("/pc/parts/all/")
                        && !request.getRequestURL().toString().contains("/pc/partsDated/all/")
                        && !request.getRequestURL().toString().contains("/pcfuwuRepair/service/Addrepair")
                        && !request.getRequestURL().toString().contains("/pc/pingequipment/parts")) {
                    if(StringUtils.isEmpty(token)){
                        throw new BusinessException(BaseResponseCode.TOKEN_ERROR);
                    }
                    CustomPasswordToken customPasswordToken=new CustomPasswordToken(token);
                    getSubject(servletRequest, servletResponse).login(customPasswordToken);
                }
            }else if(loginType.equals("app")) {  //APP或者小程序接口请求
                if(StringUtils.isEmpty(token)){
                    customRsponse(9999,"token为空",servletResponse);
                    return false;
                }else {
                    JwtTokenUtil jwtU = new JwtTokenUtil();
                    Long userId = jwtU.getUserId(token);
                    if(userId == null) {
                        customRsponse(9999,"token过期，请重新获取",servletResponse);
                        return false;
                    }else {
                        //customRsponse(200,"",servletResponse);
                        return false;
                    }
                }

            }

        }catch (BusinessException exception){
            if(HttpContextUtils.isAjaxRequest(request)){
                customRsponse(exception.getMessageCode(),exception.getDetailMessage(),servletResponse);
            }else if(exception.getMessageCode()==BaseResponseCode.TOKEN_ERROR.getCode()){
//                servletRequest.getRequestDispatcher("/index/login").forward(servletRequest,servletResponse);
                customRsponse(exception.getMessageCode(),exception.getDetailMessage(),servletResponse);
            }else if(exception.getMessageCode()==BaseResponseCode.UNAUTHORIZED_ERROR.getCode()){
                customRsponse(403,exception.getDetailMessage(),servletResponse);
            }else {
                customRsponse(500,exception.getDetailMessage(),servletResponse);
            }
            return false;
        } catch (AuthenticationException e){
            if(HttpContextUtils.isAjaxRequest(request)){
                if(e.getCause() instanceof BusinessException){
                    BusinessException exception= (BusinessException) e.getCause();
                    customRsponse(exception.getMessageCode(),exception.getDetailMessage(),servletResponse);
                }else {
                    customRsponse(BaseResponseCode.SYSTEM_BUSY.getCode(),BaseResponseCode.SYSTEM_BUSY.getMsg(),servletResponse);
                }
            }else {
                customRsponse(403,BaseResponseCode.SYSTEM_BUSY.getMsg(),servletResponse);
            }
            return false;
        }catch (Exception e) {
            if(HttpContextUtils.isAjaxRequest(request)){
                if(e.getCause() instanceof BusinessException){
                    BusinessException exception= (BusinessException) e.getCause();
                    customRsponse(exception.getMessageCode(),exception.getDetailMessage(),servletResponse);
                }else {
                    customRsponse(BaseResponseCode.SYSTEM_BUSY.getCode(),BaseResponseCode.SYSTEM_BUSY.getMsg(),servletResponse);
                }
            }else {
                customRsponse(500,BaseResponseCode.SYSTEM_BUSY.getMsg(),servletResponse);
            }
            return false;
        }
        return true;
    }

    private void customRsponse(int code,String msg,ServletResponse response){
        try {
            DataResult result = DataResult.getResult(code,msg);

            response.setContentType("application/json; charset=utf-8");
            response.setCharacterEncoding("UTF-8");

            String userJson = JSON.toJSONString(result);
            OutputStream out = response.getOutputStream();
            out.write(userJson.getBytes("UTF-8"));
            out.flush();
        } catch (IOException e) {
            log.error("eror={}",e);
        }
    }

}
